package com.tj.ocr.img;

import org.budo.support.java.awt.image.util.BufferedImageUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

public class BlankWhiteUtil {

	public static int SIM_THD = 60;
	public static int BK_R = 4;
	public static int BK_G = 169;
	public static int BK_B = 254;
	public static int BK_THD = 20;

	public static int max = Color.black.getRGB();// new Color(0, 0, 0).getRGB();
	public static int min = Color.white.getRGB();// new Color(0, 0, 0).getRGB();

	/**
	 * 判定是否是相似颜色的像素
	 * 
	 * @param A：点a
	 * @param B：点b
	 * @param opy
	 *            ：是否有渐变
	 * @return
	 */
	public static boolean isSimilary(int A, int B, boolean opy) {
		if (opy) {
			int ra = (A & 0xff0000) >> 16;
			int ga = (A & 0xff00) >> 8;
			int ba = (A & 0xff);

			int rb = (B & 0xff0000) >> 16;
			int gb = (B & 0xff00) >> 8;
			int bb = (B & 0xff);

			return (Math.abs(ra - rb) < SIM_THD && Math.abs(ga - gb) < SIM_THD && Math.abs(ba - bb) < SIM_THD);
		} else {
			return A == B;
		}
	}

	public static boolean isSimilary(int A, int B) {
		return isSimilary(A, B, true);
	}

	public static int sim(int A, int B) {
		int ra = (A & 0xff0000) >> 16;
		int ga = (A & 0xff00) >> 8;
		int ba = (A & 0xff);

		int rb = (B & 0xff0000) >> 16;
		int gb = (B & 0xff00) >> 8;
		int bb = (B & 0xff);

		return (Math.abs(ra - rb) + Math.abs(ga - gb) + Math.abs(ba - bb));
	}

    @SuppressWarnings("unused")
    public static BufferedImage removeBJ(BufferedImage image) {
		int w = image.getWidth();
		int h = image.getHeight();

		for (int y = 0; y < h; y++) {
			// get bj
			int pixel1 = image.getRGB(w - 1, y);
			int pixel2 = image.getRGB(w - 3, y);
			int pixel3 = image.getRGB(w - 5, y);
			int pixel4 = image.getRGB(w - 7, y);
			int pixel5 = image.getRGB(0, y);

			boolean opy = pixel5 != pixel1;
			if (isSimilary(pixel1, pixel2) && isSimilary(pixel2, pixel3) && isSimilary(pixel3, pixel4)) {
				int ll = 0;
				ll++;
				boolean ff = isBlank(pixel1);
				// if(pixel1 == pixel2 && pixel2 == pixel3 && pixel3 == pixel4){
				for (int x = w - 1; x > -1; x--) {
					int pixel = image.getRGB(x, y);
					if (isSimilary(pixel, pixel1, opy)) {
						if (sim(pixel1, pixel) < 10)
							pixel1 = pixel;
						image.setRGB(x, y, min);
					} else {
						if (ff)
							image.setRGB(x, y, reverse(pixel));
					}
				}
			}
		}

		return image;
	}
	
	public static void  rgb(int rgb, int[] ret){
		 ret[0] = (rgb >> 16) & 0xff;
		 ret[1] = (rgb >> 8) & 0xff;
		 ret[2] = rgb & 0xff;
	}
	
	public static BufferedImage removeBJ(BufferedImage image, float a) {
		int w = image.getWidth();
		int h = image.getHeight();
		int[] bkRGB = new int[3];
		int[] cuRGB = new int[3];
		
		for (int y = 0; y < h; y++) {
			// get bj
			int pixel1 = image.getRGB(w - 2, y);
			int pixel2 = image.getRGB(w - 3, y);
			int pixel3 = image.getRGB(w - 4, y);
			
			int pixel5 = image.getRGB(0, y);

			boolean opy = pixel5 != pixel1;
			if (isSimilary(pixel1, pixel2) && isSimilary(pixel2, pixel3)) {
				rgb(pixel1, bkRGB);
				//rr = (pixel_r - pixel1_r * a * (1-a))/a;
				
				// if(pixel1 == pixel2 && pixel2 == pixel3 && pixel3 == pixel4){
				for (int x = w - 1; x > -1; x--) {
					int pixel = image.getRGB(x, y);
					rgb(pixel, cuRGB);
					
					if (isSimilary(pixel, pixel1, opy)) {
						/*if (sim(pixel1, pixel) < 10)
							pixel1 = pixel;*/
						image.setRGB(x, y, min);
					} else {
						//获取色系
						if(bkRGB[0] > bkRGB[1] && bkRGB[0] > bkRGB[2]){//r
							if(Math.abs(cuRGB[0] - bkRGB[0]) < 70){//sim
								image.setRGB(x, y, min);
							}
						}else if(bkRGB[1] > bkRGB[0] && bkRGB[1] > bkRGB[2]){//r
							if(Math.abs(cuRGB[1] - bkRGB[1]) < 70){//sim
								image.setRGB(x, y, min);
							}
						}else if(bkRGB[2] > bkRGB[0] && bkRGB[2] > bkRGB[1]){//b
							if(Math.abs(cuRGB[2] - bkRGB[2]) < 70){//sim
								image.setRGB(x, y, min);
							}
						}/*
						rgb(pixel, cuRGB);
						int rr = (int) ((cuRGB[0] * 100 - bkRGB[0] * (100 - a)) / a);
						int rg = (int) ((cuRGB[1] * 100 - bkRGB[1] * (100 - a)) / a);
						int rb = (int) ((cuRGB[2] * 100 - bkRGB[2] * (100 - a)) / a);
						image.setRGB(x, y, (new Color(rr,rg,rb)).getRGB());*/
						//image.setRGB(x, y, (new Color(cuRGB[0],cuRGB[1],cuRGB[2])).getRGB());
					}
				}
			}
		}

		//for test
		//ImageRW.write(image, "d:\\test\\pp.png");
		
		return image;
	}

	public static boolean isBlank(int A) {
		int ra = (A & 0xff0000) >> 16;
		int ga = (A & 0xff00) >> 8;
		int ba = (A & 0xff);

		return Math.abs(ra - BK_R) < BK_THD && Math.abs(ga - BK_G) < BK_THD && Math.abs(ba - BK_B) < BK_THD;
	}

	public static boolean isBlankEx(int A) {
		return A == max;
	}

	public static int reverse(int p) {
		int a = (p >> 24) & 0xff;
		int r = (p >> 16) & 0xff;
		int g = (p >> 8) & 0xff;
		int b = p & 0xff;

		r = 255 - r;
		g = 255 - g;
		b = 255 - b;

		return (a << 24) | (r << 16) | (g << 8) | b;
	}

	public static BufferedImage proc(BufferedImage image, int threslhod) {
		MyImage mi = procEx(image,threslhod);
		
		BufferedImage img = mi.getImage();
		for(int x=0;x<mi.getWidth();x++){
			for(int y=0;y<mi.getHeight();y++){
				if(mi.getData()[x][y]==1)
					img.setRGB(x, y, max);
				else
					img.setRGB(x, y, min);
			}
		}
		
		return img;
	}

	public static MyImage procEx(BufferedImage image, int threslhod) {
		MyImage ret = new MyImage(image);
		
		int w = image.getWidth();
		int h = image.getHeight();
		int[] data_line = ret.getData_line();
		int[] bkRGB = new int[3];
		int[] cuRGB = new int[3];
		int[][] zuobiao = ret.getData();

		for (int y = 0; y < h; y++) {
			// get bj
			//int pixel1 = image.getRGB(w - 1, y);
			int pixel2 = BufferedImageUtil.getRGB_0(image, w - 2, y);
			int pixel3 = BufferedImageUtil.getRGB_0(image, w - 3, y);
			int pixel4 = BufferedImageUtil.getRGB_0(image, w - 4, y);

			//boolean opy = pixel5 != pixel2;
			if (Math.abs(pixel3 - pixel2) < SIM_THD && Math.abs(pixel3 - pixel4) < SIM_THD) {
				bkRGB[0] = (pixel2 >> 16) & 0xff;
				bkRGB[1] = (pixel2 >> 8) & 0xff;
				bkRGB[2] = pixel2 & 0xff;
				//rgb(pixel2, bkRGB);
				//rr = (pixel_r - pixel1_r * a * (1-a))/a;
				
				// if(pixel1 == pixel2 && pixel2 == pixel3 && pixel3 == pixel4){
				for (int x = w - 1; x > -1; x--) {
					int pixel = image.getRGB(x, y);
					//rgb(pixel, cuRGB);
					
					if (Math.abs(pixel - pixel2) < SIM_THD) {
						/*if (sim(pixel1, pixel) < 10)
							pixel1 = pixel;*/
						//image.setRGB(x, y, min);
					} else {
						cuRGB[0] = (pixel >> 16) & 0xff;
						cuRGB[1] = (pixel >> 8) & 0xff;
						cuRGB[2] = pixel & 0xff;
						int baseCu =0, baseBk = 0;
						//获取色系
						if(bkRGB[0] > bkRGB[1] && bkRGB[0] > bkRGB[2]){//r
							baseCu = cuRGB[0];
							baseBk = bkRGB[0];
						}else if(bkRGB[1] > bkRGB[0] && bkRGB[1] > bkRGB[2]){//r
							baseCu = cuRGB[1];
							baseBk = bkRGB[1];
						}else if(bkRGB[2] > bkRGB[0] && bkRGB[2] > bkRGB[1]){//r
							baseCu = cuRGB[2];
							baseBk = bkRGB[2];
						}else{
							baseCu = (cuRGB[0] + cuRGB[1] + cuRGB[2]) / 3;
							baseBk = (bkRGB[0] + bkRGB[1] + bkRGB[2]) / 3;
						}
						
						if(Math.abs(baseCu - baseBk) < 70){//sim
							//image.setRGB(x, y, min);
						}else if( (cuRGB[0] + cuRGB[1] + cuRGB[2]) / 3 <= threslhod){
							//image.setRGB(x, y, max);
							data_line[y] = 1;
							zuobiao[x][y] = 1;
						}else{
							//image.setRGB(x, y, min);
							//zuobiao[x][y] = 0;
						}
					}
				}
			}
		}
		
		// get backgroud color
		//removeBJ(image, 0);

		/*int[] rgb = new int[3];

		BufferedImage bi = image;//new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
		int SW = threslhod;
		for (int x = 0; x < w; x++) {
			for (int y = 0; y < h; y++) {
				int pixel = image.getRGB(x, y);
				rgb[0] = (pixel & 0xff0000) >> 16;
				rgb[1] = (pixel & 0xff00) >> 8;
				rgb[2] = (pixel & 0xff);

				if( (rgb[0] + rgb[1] + rgb[2]) / 3 <= SW){
					bi.setRGB(x, y, max);
					zuobiao[x][y] = 1;
				}else{
					bi.setRGB(x, y, min);
					zuobiao[x][y] = 0;
				}
			}
		}*/
		
		return ret;

	}

	public static void main(String[] args) {
		BufferedImage img = ImageRW.read("d:\\test\\t1.png");
		// ImageRW.write(removeBJ(img), "c:\\test\\2.jpg");
		//MyImage img2 = procEx(img,170);
		img = removeBJ(img, 90);
		ImageRW.write(img, "d:\\test\\bbb30.png");
		img = proc(img,170);
		ImageRW.write(img, "d:\\test\\bbb33.png");

		// List<CPos> lp = LineParser.parseLines(img, 0, 0, -1);
		// splitImage
		// SplitImage(img,lp);

		System.out.println("ok");
	}
}
